Fixup `SMCCC_ARCH_FEATURES` semantics
authorDimitris Papastamos <[email protected]>
Mon, 12 Mar 2018 14:47:09 +0000 (14:47 +0000)
committerDimitris Papastamos <[email protected]>
Wed, 14 Mar 2018 11:19:53 +0000 (11:19 +0000)
When querying `SMCCC_ARCH_WORKAROUND_1` through `SMCCC_ARCH_FEATURES`,
return either:
  * -1 to indicate the PE on which `SMCCC_ARCH_FEATURES` is called
    requires firmware mitigation for CVE-2017-5715 but the mitigation
    is not compiled in.
  * 0 to indicate that firmware mitigation is required, or
  * 1 to indicate that no firmware mitigation is required.

This patch complies with v1.2 of the firmware interfaces
specification (ARM DEN 0070A).

Change-Id: Ibc32d6620efdac6c340758ec502d95554a55f02a
Signed-off-by: Dimitris Papastamos <[email protected]>
bl31/bl31.mk
include/lib/cpus/aarch64/cpu_macros.S
include/lib/cpus/workaround_cve_2017_5715.h [new file with mode: 0644]
lib/cpus/aarch64/cortex_a57.S
lib/cpus/aarch64/cortex_a72.S
lib/cpus/aarch64/cortex_a73.S
lib/cpus/aarch64/cortex_a75.S
lib/cpus/aarch64/cpu_helpers.S
services/arm_arch_svc/arm_arch_svc_setup.c

index 886d3016ff4dee9803ac6276184f9437b2eac574..0e47ddf68127c0bc96bfd032ef8ef173c62f7a9d 100644 (file)
@@ -61,8 +61,8 @@ BL31_SOURCES          +=      lib/extensions/sve/sve.c
 endif
 
 ifeq (${WORKAROUND_CVE_2017_5715},1)
-BL31_SOURCES           +=      lib/cpus/aarch64/workaround_cve_2017_5715_mmu.S         \
-                               lib/cpus/aarch64/workaround_cve_2017_5715_bpiall.S
+BL31_SOURCES           +=      lib/cpus/aarch64/workaround_cve_2017_5715_bpiall.S      \
+                               lib/cpus/aarch64/workaround_cve_2017_5715_mmu.S
 endif
 
 BL31_LINKERFILE                :=      bl31/bl31.ld.S
index 6c3a5b992f58122dfeaf52ebf151fcbc318b0625..8f0a74f0a3f397b9432f352016142e5fd1c1222f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -46,6 +46,8 @@ CPU_MIDR: /* cpu_ops midr */
 CPU_RESET_FUNC: /* cpu_ops reset_func */
        .space  8
 #endif
+CPU_EXTRA1_FUNC:
+       .space  8
 #ifdef IMAGE_BL31 /* The power down core and cluster is needed only in BL31 */
 CPU_PWR_DWN_OPS: /* cpu_ops power down functions */
        .space  (8 * CPU_MAX_PWR_DWN_OPS)
@@ -113,6 +115,10 @@ CPU_OPS_SIZE = .
         * _resetfunc:
         *      Reset function for the CPU. If there's no CPU reset function,
         *      specify CPU_NO_RESET_FUNC
+        * _extra1:
+        *      This is a placeholder for future per CPU operations.  Currently,
+        *      some CPUs use this entry to set a test function to determine if
+        *      the workaround for CVE-2017-5715 needs to be applied or not.
         * _power_down_ops:
         *      Comma-separated list of functions to perform power-down
         *      operatios on the CPU. At least one, and up to
@@ -122,8 +128,8 @@ CPU_OPS_SIZE = .
         *      CPU_MAX_PWR_DWN_OPS functions, the last specified one will be
         *      used to handle power down at subsequent levels
         */
-       .macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \
-               _power_down_ops:vararg
+       .macro declare_cpu_ops_base _name:req, _midr:req, _resetfunc:req, \
+               _extra1:req, _power_down_ops:vararg
        .section cpu_ops, "a"
        .align 3
        .type cpu_ops_\_name, %object
@@ -131,6 +137,7 @@ CPU_OPS_SIZE = .
 #if defined(IMAGE_AT_EL3)
        .quad \_resetfunc
 #endif
+       .quad \_extra1
 #ifdef IMAGE_BL31
 1:
        /* Insert list of functions */
@@ -187,6 +194,18 @@ CPU_OPS_SIZE = .
 #endif
        .endm
 
+       .macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \
+               _power_down_ops:vararg
+               declare_cpu_ops_base \_name, \_midr, \_resetfunc, 0, \
+                       \_power_down_ops
+       .endm
+
+       .macro declare_cpu_ops_workaround_cve_2017_5715 _name:req, _midr:req, \
+               _resetfunc:req, _extra1:req, _power_down_ops:vararg
+               declare_cpu_ops_base \_name, \_midr, \_resetfunc, \
+                       \_extra1, \_power_down_ops
+       .endm
+
 #if REPORT_ERRATA
        /*
         * Print status of a CPU errata
diff --git a/include/lib/cpus/workaround_cve_2017_5715.h b/include/lib/cpus/workaround_cve_2017_5715.h
new file mode 100644 (file)
index 0000000..e837a67
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __WORKAROUND_CVE_2017_5715_H__
+#define __WORKAROUND_CVE_2017_5715_H__
+
+int check_workaround_cve_2017_5715(void);
+
+#endif /* __WORKAROUND_CVE_2017_5715_H__ */
index c82ebfc95179a29f33f27b105f4ca2475447b016..4d072e11c6489250df860d622a567bc70bcc4fab 100644 (file)
@@ -555,8 +555,8 @@ func cortex_a57_cpu_reg_dump
        ret
 endfunc cortex_a57_cpu_reg_dump
 
-
-declare_cpu_ops cortex_a57, CORTEX_A57_MIDR, \
+declare_cpu_ops_workaround_cve_2017_5715 cortex_a57, CORTEX_A57_MIDR, \
        cortex_a57_reset_func, \
+       check_errata_cve_2017_5715, \
        cortex_a57_core_pwr_dwn, \
        cortex_a57_cluster_pwr_dwn
index 199820ccd3a09cd1d643e4d6c62402d25503448f..29fa77b90123bcdf65c98e513f44ac645e825eb1 100644 (file)
@@ -292,8 +292,8 @@ func cortex_a72_cpu_reg_dump
        ret
 endfunc cortex_a72_cpu_reg_dump
 
-
-declare_cpu_ops cortex_a72, CORTEX_A72_MIDR, \
+declare_cpu_ops_workaround_cve_2017_5715 cortex_a72, CORTEX_A72_MIDR, \
        cortex_a72_reset_func, \
+       check_errata_cve_2017_5715, \
        cortex_a72_core_pwr_dwn, \
        cortex_a72_cluster_pwr_dwn
index 63d16f9db11dbf6d71b03b37669afe59114dfaf8..0a961ea3336bed7edd66b7014e264f9899a75640 100644 (file)
@@ -170,7 +170,8 @@ func cortex_a73_cpu_reg_dump
        ret
 endfunc cortex_a73_cpu_reg_dump
 
-declare_cpu_ops cortex_a73, CORTEX_A73_MIDR, \
+declare_cpu_ops_workaround_cve_2017_5715 cortex_a73, CORTEX_A73_MIDR, \
        cortex_a73_reset_func, \
+       check_errata_cve_2017_5715, \
        cortex_a73_core_pwr_dwn, \
        cortex_a73_cluster_pwr_dwn
index d10279516786ac0bba74b667c074df45427d4605..288f5afedb4a7fab9ad0f2f9c029455fd24bb77d 100644 (file)
@@ -113,6 +113,7 @@ func cortex_a75_cpu_reg_dump
        ret
 endfunc cortex_a75_cpu_reg_dump
 
-declare_cpu_ops cortex_a75, CORTEX_A75_MIDR, \
+declare_cpu_ops_workaround_cve_2017_5715 cortex_a75, CORTEX_A75_MIDR, \
        cortex_a75_reset_func, \
+       check_errata_cve_2017_5715, \
        cortex_a75_core_pwr_dwn
index ae1c3c25259700e28c222512e19afac80e22ac2b..5a9226d8326430fe0d1dc8615d9b026f33fa8b61 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,9 +7,7 @@
 #include <arch.h>
 #include <asm_macros.S>
 #include <assert_macros.S>
-#if defined(IMAGE_BL31) || (defined(IMAGE_BL2) && BL2_AT_EL3)
 #include <cpu_data.h>
-#endif
 #include <cpu_macros.S>
 #include <debug.h>
 #include <errata_report.h>
@@ -281,3 +279,36 @@ func print_errata_status
        br      x1
 endfunc print_errata_status
 #endif
+
+/*
+ * int check_workaround_cve_2017_5715(void);
+ *
+ * This function returns:
+ *  - ERRATA_APPLIES when firmware mitigation is required.
+ *  - ERRATA_NOT_APPLIES when firmware mitigation is _not_ required.
+ *  - ERRATA_MISSING when firmware mitigation would be required but
+ *    is not compiled in.
+ *
+ * NOTE: Must be called only after cpu_ops have been initialized
+ *       in per-CPU data.
+ */
+       .globl  check_workaround_cve_2017_5715
+func check_workaround_cve_2017_5715
+       mrs     x0, tpidr_el3
+#if ENABLE_ASSERTIONS
+       cmp     x0, #0
+       ASM_ASSERT(ne)
+#endif
+       ldr     x0, [x0, #CPU_DATA_CPU_OPS_PTR]
+       ldr     x0, [x0, #CPU_EXTRA1_FUNC]
+       /*
+        * If the reserved function pointer is NULL, this CPU
+        * is unaffected by CVE-2017-5715 so bail out.
+        */
+       cmp     x0, #0
+       beq     1f
+       br      x0
+1:
+       mov     x0, #ERRATA_NOT_APPLIES
+       ret
+endfunc check_workaround_cve_2017_5715
index a809c429a047851211ecfde8f6e1201b20bc512a..f75a737e9f5f56c84da01d06d4a8577113abf98e 100644 (file)
@@ -6,9 +6,11 @@
 
 #include <arm_arch_svc.h>
 #include <debug.h>
+#include <errata_report.h>
 #include <runtime_svc.h>
 #include <smcc.h>
 #include <smcc_helpers.h>
+#include <workaround_cve_2017_5715.h>
 
 static int32_t smccc_version(void)
 {
@@ -17,14 +19,19 @@ static int32_t smccc_version(void)
 
 static int32_t smccc_arch_features(u_register_t arg)
 {
+       int ret;
+
        switch (arg) {
        case SMCCC_VERSION:
        case SMCCC_ARCH_FEATURES:
                return SMC_OK;
-#if WORKAROUND_CVE_2017_5715
        case SMCCC_ARCH_WORKAROUND_1:
-               return SMC_OK;
-#endif
+               ret = check_workaround_cve_2017_5715();
+               if (ret == ERRATA_APPLIES)
+                       return 0;
+               else if (ret == ERRATA_NOT_APPLIES)
+                       return 1;
+               return -1; /* ERRATA_MISSING */
        default:
                return SMC_UNK;
        }